import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../app_config.dart';

class AuthService {
  static final AuthService _instance = AuthService._internal();

  factory AuthService() => _instance;

  AuthService._internal();

  Future<bool> login(String username, String password) async {
    try {
      final dio = Dio(BaseOptions(baseUrl: AppConfig.apiBaseUrl));
      final response = await dio.post('/admin/login', data: {
        'username': username,
        'password': password,
      });

      if (response.statusCode == 200 && response.data['access_token'] != null && response.data['refresh_token'] != null) {
        await _saveTokens(response.data['access_token'], response.data['refresh_token']);
        return true;
      }
      return false;
    } catch (e) {
      return false;
    }
  }

  Future<void> logout() async {
    try {
      final accessToken = await getAccessToken();
      if (accessToken != null) {
        final dio = Dio(BaseOptions(
          baseUrl: AppConfig.apiBaseUrl,
          headers: {'Authorization': 'Bearer $accessToken'},
        ));
        // 调用后端登出接口，使 token 失效
        await dio.post('/admin/logout');
      }
    } catch (e) {
      // 即使后端调用失败，也要清除本地 token
    } finally {
      final prefs = await SharedPreferences.getInstance();
      await prefs.remove(AppConfig.accessTokenKey);
    }
  }

  Future<String?> getAccessToken() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(AppConfig.accessTokenKey);
  }

  Future<String?> getRefreshToken() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(AppConfig.refreshTokenKey);
  }

  Future<bool> isAuthenticated() async {
    final accessToken = await getAccessToken();
    return accessToken != null;
  }

  Future<void> _saveTokens(String accessToken, String refreshToken) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(AppConfig.accessTokenKey, accessToken);
    await prefs.setString(AppConfig.refreshTokenKey, refreshToken);
  }

  Future<bool> refreshToken() async {
    try {
      final refreshToken = await getRefreshToken();
      if (refreshToken == null) return false;

      final dio = Dio(BaseOptions(baseUrl: AppConfig.apiBaseUrl, headers: {'Authorization': 'Bearer $refreshToken'}));

      final response = await dio.post('/admin/refresh-token');
      if (response.statusCode == 200 && response.data['access_token'] != null && response.data['refresh_token'] != null) {
        await _saveTokens(response.data['access_token'], response.data['refresh_token']);
        return true;
      }
      return false;
    } catch (e) {
      return false;
    }
  }

  // 检查 token 是否即将过期
  Future<bool> shouldRefreshToken() async {
    final token = await getAccessToken();
    if (token == null) return false;

    try {
      // 解析 JWT token
      final parts = token.split('.');
      if (parts.length != 3) return false;

      final payload = parts[1];
      final normalized = base64Url.normalize(payload);
      final decoded = utf8.decode(base64Url.decode(normalized));
      final data = json.decode(decoded);

      // 获取过期时间
      final exp = data['exp'] as int;
      final expDate = DateTime.fromMillisecondsSinceEpoch(exp * 1000);
      final now = DateTime.now();

      // 如果 token 将在 5 分钟内过期，则需要刷新
      return expDate.difference(now).inMinutes <= 5;
    } catch (e) {
      return false;
    }
  }
}
